package com.taobao.aft.format;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

import com.taobao.aft.exception.AofTranslateException;
import com.taobao.inter.SplitInterface;

public class AofHSetCmdFormatBuilder extends CmdFormat {
	private final static String COMMAND = "HSET";
	private final static String CMDARGC = "4";
	private final static String CMDNAMELEN = "4";
	
	private static AofHSetCmdFormatBuilder ab = null;
	
	private static SplitInterface sif = new SplitInterface() {
		
		@Override
		public String[] split(String data) {
			data = data.trim();
			return data.split("\\s+");
		}
	};
	
	
	@Override
	public CmdFormat createInstance() {
		if(ab == null) {
			ab = new AofHSetCmdFormatBuilder();
		}
		return ab;
	}
	
	public static void setSplitFunc(SplitInterface split) {
		sif = split;
	}
	
	private ByteBuffer getAofHeaderFormat(ByteBuffer byteBuffer)
			throws UnsupportedEncodingException {
		//*3\r\n
		byteBuffer.put(ARGCFLAG.getBytes(CHARSET));
		byteBuffer.put(CMDARGC.getBytes(CHARSET));
		byteBuffer.put(CLR.getBytes(CHARSET));
		
		//$6\r\n
		byteBuffer.put(CMDLENFLAG.getBytes(CHARSET));
		byteBuffer.put(CMDNAMELEN.getBytes(CHARSET));
		byteBuffer.put(CLR.getBytes());
		
		//SET\r\n
		byteBuffer.put(COMMAND.getBytes(CHARSET));
		byteBuffer.put(CLR.getBytes(CHARSET));
		
		return byteBuffer;
	}
	
	private ByteBuffer getAofKeyFormat(ByteBuffer byteBuffer, byte[] byteKey)
			throws UnsupportedEncodingException {	
		
		//$len\r\n
		byteBuffer.put(CMDLENFLAG.getBytes(CHARSET));
		byteBuffer.put(String.valueOf(byteKey.length).getBytes(CHARSET));
		byteBuffer.put(CLR.getBytes(CHARSET));
		
		//key\r\n
		byteBuffer.put(byteKey);
		byteBuffer.put(CLR.getBytes(CHARSET));
		
		return byteBuffer;
	}
	
	private ByteBuffer getAofFieldFormat(ByteBuffer byteBuffer, byte[] byteField)
			throws UnsupportedEncodingException{
		
		//$len\r\n
		byteBuffer.put(CMDLENFLAG.getBytes(CHARSET));
		byteBuffer.put(String.valueOf(byteField.length).getBytes(CHARSET));
		byteBuffer.put(CLR.getBytes(CHARSET));
		
		//value\r\n
		byteBuffer.put(byteField);
		byteBuffer.put(CLR.getBytes(CHARSET));
		
		return byteBuffer;
	}
	
	private ByteBuffer getAofValueFormat(ByteBuffer byteBuffer, byte[] byteValue)
			throws UnsupportedEncodingException{
		
		//$len\r\n
		byteBuffer.put(CMDLENFLAG.getBytes(CHARSET));
		byteBuffer.put(String.valueOf(byteValue.length).getBytes(CHARSET));
		byteBuffer.put(CLR.getBytes(CHARSET));
		
		//value\r\n
		byteBuffer.put(byteValue);
		byteBuffer.put(CLR.getBytes(CHARSET));
		
		return byteBuffer;
	}
	
	public byte[] getAofFormat(String data) throws AofTranslateException{
		String[] splitString = sif.split(data);
		if(splitString == null || splitString.length != 3) {
			throw new AofTranslateException("split failed "
					+ splitString.length);
		}

		byte[] byteKey = null;
		byte[] byteField = null;
		byte[] byteValue = null;
		try {
			byteKey = splitString[0].getBytes(CHARSET);
			byteField = splitString[1].getBytes(CHARSET);
			byteValue = splitString[1].getBytes(CHARSET);
		} catch (UnsupportedEncodingException e1) {
			throw new AofTranslateException();
		}
		
		
		ByteBuffer byteBuffer =
				ByteBuffer.allocate(128 + byteKey.length + byteValue.length);
		byteBuffer.clear();
		
		try {
			byteBuffer = getAofHeaderFormat(byteBuffer);
			byteBuffer = getAofKeyFormat(byteBuffer, byteKey);
			byteBuffer = getAofFieldFormat(byteBuffer, byteField);
			byteBuffer = getAofValueFormat(byteBuffer, byteValue);
		} catch (UnsupportedEncodingException e) {
			throw new AofTranslateException();
		}
		byte[] buffer = new byte[byteBuffer.position()];
		System.arraycopy(byteBuffer.array(), 0, buffer, 0, byteBuffer.position());
		return buffer;
	}
}
